package com.sy.core.base.controller;

import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.sy.core.base.model.SimpleModel;
import com.sy.core.base.service.BaseServiceImpl;
import com.sy.core.exception.BusinessException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.propertyeditors.CustomBooleanEditor;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.beans.propertyeditors.CustomNumberEditor;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.Set;


/**
 * 控制层基类
 *
 * @param <T>
 */
public abstract class BaseController<T extends SimpleModel> {

    public Logger logger = LoggerFactory.getLogger(BaseController.class);

    private static final char SP = '/';// File.separatorChar;


    protected static Set<String> excludeSearchSet = Sets.newHashSet("page",
            "pageSize", "dir", "sort");

    protected ResultObj resultObj = new ResultObj();// 封装一个统一对象用于返回前台


    /**
     * 前台指与对象之间的类型转换
     *
     * @param binder
     * @param request
     */
    @InitBinder
    public void initBinder(WebDataBinder binder, WebRequest request) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        dateFormat.setLenient(false);
        binder.registerCustomEditor(Date.class, new CustomDateEditor(
                dateFormat, true));
        binder.registerCustomEditor(String.class,
                new StringTrimmerEditor(false));
        binder.registerCustomEditor(BigDecimal.class, new CustomNumberEditor(
                BigDecimal.class, true));
        binder.registerCustomEditor(Integer.class, null,
                new CustomNumberEditor(Integer.class, null, true));
        binder.registerCustomEditor(int.class, null, new CustomNativeEditor(
                Integer.class, null, true));
        binder.registerCustomEditor(Long.class, null, new CustomNumberEditor(
                Long.class, null, true));
        binder.registerCustomEditor(long.class, null, new CustomNativeEditor(
                Long.class, null, true));
        binder.registerCustomEditor(Float.class, new CustomNumberEditor(
                Float.class, true));
        binder.registerCustomEditor(Double.class, new CustomNumberEditor(
                Double.class, true));
        binder.registerCustomEditor(BigInteger.class, new CustomNumberEditor(
                BigInteger.class, true));
        binder.registerCustomEditor(BigDecimal.class, new CustomNumberEditor(
                BigDecimal.class, true));

        binder.registerCustomEditor(boolean.class, new CustomBooleanEditor(true));
        binder.registerCustomEditor(boolean.class, new CustomBooleanEditor("1", "0", true));
        binder.registerCustomEditor(Boolean.class, new CustomBooleanEditor(true));
        binder.registerCustomEditor(Boolean.class, new CustomBooleanEditor("1", "0", true));

    }


    /**
     * 把搜索值转为map，供后台及界面使用
     *
     * @param request
     * @return
     */
    public Map<String, Object> getSearchMap(HttpServletRequest request) {
        Map map = request.getParameterMap();
        Map<String, Object> m = Maps.newHashMap();
        //m = Maps.newHashMap();
        for (Object key : map.keySet()) {
            String keyStr = key.toString();
            if (!Strings.isNullOrEmpty(keyStr)) {
                if (!excludeSearchSet.contains(keyStr)) {
                    try {
                        m.put(keyStr, java.net.URLDecoder.decode(
                                request.getParameter(key.toString()), "UTF-8"));
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

        return m;
    }


    /**
     * 跳转到视图页面，具有业务规则，通过控制类的包名及类名自动解析视图路径
     *
     * @param url 模板路径 <br>
     *            替换规则：业务包名/业务名-url 如传入customer模块传入
     *            list，则自动替换为customer/customer-list
     * @return
     * @throws BusinessException
     */
    public ModelAndView view(String url) throws Exception {
        String businessPack = getBusinessPack();
        String className = getClassModelName();
        url = businessPack + SP + className + "-" + url;

        return viewfull(url);
    }

    /**
     * 跳转到视图页面，没有业务规则，需要传入完整的url
     *
     * @param url 跳转页面路径
     * @return
     */
    public ModelAndView viewfull(String url) {

        ModelAndView mv = new ModelAndView(url);
//        if (m != null) {
//            for (String key : m.keySet()) {
//                mv.addObject(key, m.get(key));
//            }
//        }
        return mv;
    }

    /**
     * 获取业务包名
     *
     * @return
     * @throws BusinessException
     */
    public String getBusinessPack() throws Exception {
        String packagePath = this.getClass().getPackage().getName();
        int controllerIndex = packagePath.indexOf("controller");
        if (controllerIndex == -1) {
            throw new BusinessException("控制层包名不包含controller.");
        }
        String p = packagePath.substring(0, controllerIndex - 1);
        int lastPotinIndex = p.lastIndexOf('.');
        String p2 = p.substring(lastPotinIndex + 1);
        p = packagePath.substring(0, lastPotinIndex);
        lastPotinIndex = p.lastIndexOf('.');
        String p1 = p.substring(lastPotinIndex + 1);
        return p1 + SP + p2;
    }

    /**
     * 获取业务名称
     *
     * @return
     */
    public String getClassModelName() {
        String n = this.getClass().getSimpleName().replace("Controller", "");
        return n.substring(0, 1).toLowerCase() + n.substring(1);
    }


}
